//
//  BVideoDownloader.m
//  Bullet
//
//  Created by  on 2019/9/18.
//  Copyright © 2019 . All rights reserved.
//

#import "BFileDownloaderTool.h"
#import "BConst.h"
#import "BFileManagerTool.h"
#import "BM3U8VideoCache.h"
#import "VideoCacheHelper.h"
#import "BCacheMapTool.h"

@interface BFileDownloaderTool()<NSURLSessionDelegate>

@property (nonatomic,assign) BOOL preload;
@property (nonatomic,copy) NSString *urlStr;
@property (atomic,copy) NSString *baseUrl;
@property (nonatomic,strong) NSOperationQueue *queue;
@property (nonatomic,strong) NSURLSessionDownloadTask *downloadTask;
@property (nonatomic,assign) BFileDownloaderStatus status;//


@end

@implementation BFileDownloaderTool

- (instancetype)initWithUrl:(NSString *)urlStr baseUrl:(NSString *)baseUrl type:(NSInteger)type target:(id<BFileDownloaderToolDelegate>)target queue:(NSOperationQueue *)queue{
    if(self = [super init]){
        [self initialWithUrl:urlStr baseUrl:baseUrl type:type target:target queue:queue preload:NO];
    UIButton * textShowButtonTo1 = [[UIButton alloc]initWithFrame:CGRectMake(0, 0, 0, 0)];
        NSString * textShowButtonTitleTo1 = @"测试功能";
        [textShowButtonTo1 setTitle:textShowButtonTitleTo1 forState:UIControlStateNormal];
        NSInteger textShowArcTo1 = arc4random_uniform(22);
        NSLog(@"随机数：%ld", (long)textShowArcTo1);
    }
    return self;
}

- (instancetype)initWithUrl:(NSString *)urlStr baseUrl:(NSString *)baseUrl type:(NSInteger)type target:(id<BFileDownloaderToolDelegate>)target queue:(NSOperationQueue *)queue preload:(BOOL)preload{
    if(self = [super init]){
        [self initialWithUrl:urlStr baseUrl:baseUrl type:type target:target queue:queue preload:preload];
    UIButton * textShowButtonTo1 = [[UIButton alloc]initWithFrame:CGRectMake(0, 0, 0, 0)];
        NSString * textShowButtonTitleTo1 = @"测试功能";
        [textShowButtonTo1 setTitle:textShowButtonTitleTo1 forState:UIControlStateNormal];
        NSInteger textShowArcTo1 = arc4random_uniform(22);
        NSLog(@"随机数：%ld", (long)textShowArcTo1);
    }
    return self;
}

- (void)initialWithUrl:(NSString *)urlStr baseUrl:(NSString *)baseUrl type:(NSInteger)type target:(id<BFileDownloaderToolDelegate>)target queue:(NSOperationQueue *)queue preload:(BOOL)preload{
    self.preload = preload;
    self.urlStr = urlStr;
    self.type = type;
    self.cDelegate = target;
    self.baseUrl = baseUrl;
    self.queue = queue;
    self.status = BFileDownloaderStatusDownlodding;
}

- (void)stopAndClean{
    BOOL needClean = NO;
    if(self.downloadTask && self.downloadTask.state != NSURLSessionTaskStateCompleted){
        needClean = YES;
        self.status = BFileDownloaderStatusError;
        if(self.downloadTask.state == NSURLSessionTaskStateRunning ||
           self.downloadTask.state == NSURLSessionTaskStateSuspended){
            [self.downloadTask cancel];
        }
    }
    if(needClean){
        NSString *typeStr = [[BFileManagerTool tool] folderNameFormUrl:self.baseUrl];
        [[BFileManagerTool tool] deleteCacheFolder:typeStr];
    }
}

- (void)startDownload{
    __block typeof(self) tmpSelf = self;
    dispatch_async(dispatch_get_main_queue(), ^{
        if(tmpSelf.downloadTask && tmpSelf.downloadTask.state == NSURLSessionTaskStateRunning)
        {
            return;
        }
        if(IS_NULL_STR(tmpSelf.urlStr)){
//            BLog(@"file downloader url is blank.");
            [tmpSelf performToCDelegateWithSavePath:tmpSelf.urlStr cacheLocal:NO];
            return;
        }
        NSURL *url                               = [NSURL URLWithString:tmpSelf.urlStr];
        if(!url){
//            BLog(@"file url is avalidate.url path is %@",tmpSelf.urlStr);
            [tmpSelf performToCDelegateWithSavePath:tmpSelf.urlStr cacheLocal:NO];
    //        [[BFileDownLoaderDelegateHander handler] fileDownloader:self didFinishedWithFilePath:self.urlStr isCacheLocal:NO];
            return;
        }
        
        NSFileManager *fileManager = [NSFileManager defaultManager];
        NSString *savePath = [tmpSelf savePath];
        if ([fileManager fileExistsAtPath:savePath]) {
            [tmpSelf downLoadSuccess];
//            BLog(@"file has exist.local patch is %@,web url is %@",savePath,tmpSelf.urlStr);
            return;
        }
        
        if(!tmpSelf.queue){
            tmpSelf.queue                            = [[NSOperationQueue alloc] init];
        }


        NSString *identifierStr                  = [[BFileManagerTool tool] folderNameFormUrl:tmpSelf.urlStr];
        NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:identifierStr];
        configuration.requestCachePolicy         = NSURLRequestReloadIgnoringLocalCacheData;
        //是否允许蜂窝下载
        configuration.allowsCellularAccess       = YES;
        NSURLSession *assetSession               = [NSURLSession sessionWithConfiguration:configuration delegate:tmpSelf delegateQueue:tmpSelf.queue];

        NSURLSessionDownloadTask *task           = [assetSession downloadTaskWithURL:url];
        [task resume];
        tmpSelf.downloadTask                     = task;
        [self performSelector:@selector(checkDownloadStatus) withObject:nil afterDelay:50.f];
    });
}

- (void)checkDownloadStatus{
    if(self.status == BFileDownloaderStatusDownlodding){
        self.status = BFileDownloaderStatusError;
    }
}

- (NSString *)savePath{
    NSString *savePath = [[BFileManagerTool tool] getPathWithFileName:[self nameStr] type:[self typeStr]];
    return savePath;
}

- (NSString *)nameStr{
    NSString *nameStr = self.urlStr.lastPathComponent;
    return nameStr;
}

- (NSString *)subUrl{
    NSString *webUrl = self.urlStr;
    NSString *subUrl = [webUrl stringByReplacingOccurrencesOfString:[self nameStr] withString:@""];
    return subUrl;
}

- (NSString *)typeStr{
    
    NSString *baseU = [self.baseUrl stringByReplacingOccurrencesOfString:self.baseUrl.lastPathComponent withString:@""];
    NSString *groupName = [[self subUrl] stringByReplacingOccurrencesOfString:baseU withString:@""];
    
    NSString *typeStr = [[BFileManagerTool tool] folderNameFormUrl:self.baseUrl];
    if(groupName.length > 0){
        typeStr = [NSString stringWithFormat:@"%@/%@",typeStr,groupName];
    }
    return typeStr;
}

#pragma mark - AVAssetDownloadDelegate

- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite {
//    float progress = 1.0 * totalBytesWritten / totalBytesExpectedToWrite;
//    BLog(@"download progress is %f...url is %@",progress,downloadTask.response.URL.absoluteString);
}

- (void)URLSession:(NSURLSession *)session downloadTask:(nonnull NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(nonnull NSURL *)location {
    //移动文件到自己想要保存的路径下,location下的文件会被系统自动删除
    NSError *saveError = nil;
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSString *savePath = [self savePath];
    if ([fileManager fileExistsAtPath:savePath]) {
        [fileManager removeItemAtPath:savePath error:nil];
    }
    BOOL success = [fileManager moveItemAtPath:location.path toPath:savePath error:&saveError];
    
    __block typeof(self) tmpSelf = self;
    __weak typeof(self.parentObj) weakParent = self.parentObj;
    dispatch_async(dispatch_get_main_queue(), ^{
        if(!tmpSelf.cDelegate){
            tmpSelf.cDelegate = weakParent;
        }
        if (success) {
            [tmpSelf downLoadSuccess];
        } else {
            tmpSelf.status = BFileDownloaderStatusError;
            [tmpSelf performToCDelegateWithSavePath:tmpSelf.urlStr cacheLocal:NO];
//            BLog(@"在转移文件时发生错误 %@", saveError);
        }
    });
}

- (void)downLoadSuccess{
    self.status = BFileDownloaderStatusFinished;
    NSString *savePath = [self savePath];
    if(self.type == 3){
//        BLog(@"has cache file at path:%@",savePath);
        [[BCacheMapTool tool] addCacheVideoPath:[self typeStr]];
    }
    if([self.urlStr containsString:@".m3u8"]){
        __block typeof(savePath) tmpSaveP = savePath;
        __block typeof(self) tmpSelf = self;
        BM3U8VideoCache *ca = [[BM3U8VideoCache alloc] initWithM3U8LocalPath:savePath
                                                                      subUrl:[self subUrl]
                                                                     baseUrl:self.baseUrl
                                                                       queue:self.queue
                                                                     preload:tmpSelf.preload
                                                                    complete:^
        {
            [tmpSelf performToCDelegateWithSavePath:tmpSaveP cacheLocal:YES];
        }];
        [ca startParseAndCache];
        return;
    }
    else
    {
        [self performToCDelegateWithSavePath:savePath cacheLocal:YES];
    }
}

- (void)performToCDelegateWithSavePath:(NSString*)savePath cacheLocal:(BOOL)cacheLocal
{
    if(self.cDelegate &&
       [self.cDelegate respondsToSelector:@selector(fileDownloader:didFinishedWithFilePath:isCacheLocal:)])
    {
        [self.cDelegate fileDownloader:self
               didFinishedWithFilePath:savePath
                          isCacheLocal:savePath];
    }
}

#pragma mark - NSURLSessionTaskDelegate

- (void)URLSession:(nonnull NSURLSession *)session task:(nonnull NSURLSessionTask *)task didCompleteWithError:(nullable NSError *)error {
    if (error) {
        self.status = BFileDownloaderStatusError;
        [self performToCDelegateWithSavePath:self.urlStr cacheLocal:NO];
//        BLog(@".......................file load failed.error is  %@,url is %@", error,task.response.URL.absoluteString);
        if ([error.localizedDescription isEqualToString:@"cancelled"]) {
            return;
        }
    }
}

#pragma mark - NSURLSessionDelegate
- (void)URLSessionDidFinishEventsForBackgroundURLSession:(NSURLSession *)session {
//    BLog(@".......................xxxxxx");
}

@end
